﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
using System.Diagnostics;

namespace Benchmark
{
	/// <summary>
	/// Benchmarking class by Svish @ Stackoverflow.com
	/// 
	/// http://stackoverflow.com/questions/1507405/c-is-this-benchmarking-class-accurate
	/// 
	/// Example usage:
	///		var avg = Benchmark.This(() => SomeMethod()).Take(500).Average();
	/// 
	/// </summary>
	public sealed class Benchmark : IEnumerable<long>
	{
		private readonly Action subject;
		private Benchmark(Action subject) { this.subject = subject; }

		public static Benchmark This(Action subject)
		{
			return new Benchmark(subject);
		}

		public IEnumerator<long> GetEnumerator()
		{
			subject();
			GC.Collect();
			GC.WaitForPendingFinalizers();

			var watch = new Stopwatch();
			while (true)
			{
				watch.Reset();
				watch.Start();
				subject();
				watch.Stop();
				yield return watch.Elapsed.Ticks;
			}
		}

		IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); }
	}
}
